#include "trap.h"
   .set noat
   .globl main
   .data 
    data1: .word 0x11223344
   .text
main:
    # $t0, $t1保存进行运算的两个操作数 $t2保存运算结果
    # $t3 发生错误时，标志为0xffffffff（有没有错误先看这个寄存器）
    # $at 异常标志
    # $a1 每次发生异常后，记录错误原因
    # $a2 校验错误原因，跳转到正确的异常处理程序上
    # $v0 同步增加，与$at进行校验（看这个的值确定是哪个异常的错误）
    # $v1 记录返回地址

    # integeroverflow add
    and $at, $zero, $zero 
    li $t1, 0x7fffffff 
    li $t0, 0x7fffffff 
    add $t2, $t0, $t1     # add overflow cause[6:2]=0xb
    # $at应为0x1

    # addi
    li $t0, 0x7fffffff
    addi $t2, $t0, 0x7fff # addi overflow cause[6:2]=0xb
    # $at应为0x1

    # sub
    li $t1, 0x80000000
    li $t0, 0x7fffffff
    sub $t2, $t1, $t0     # sub overflow cause[6:2]=0xb
    # $at应为0x1
    
    # break
    break                 # cause[6:2]=0x9  
    # $at应为0x9999
    
    # addrerror
    # and $at, $zero, $zero
    la $t0, data1
    sh $t1, 0x1($t0)      # sh cause[6:2]=0x5
    # $at应为0x5555

    # and $at, $zero, $zero
    la $t0, data1
    sw $t1, 0x3($t0)      # sw cause[6:2]=0x5
    # $at应为0x5555

    la $t0, data1
    lw $t1, 0x1($t0)      # lw cause[6:2]=0x4
    # $at应为0x4444

    la $t0, data1
    lh $t1, 0x3($t0)      # lh cause[6:2]=0x4
    # $at应为0x4444

    syscall               # cause[6:2]=0x8
    # $at应为0x8888
    
    li $t3, 0x12345678     # success
    HIT_GOOD_TRAP		   # stop temu

    .org 0x380
exp_ent:
    mfc0 $a1, $13 # $a1($5) = cause 
    # cause[6:2]=0x0c
    ori $a2, $zero, 0x30
    beq $a1, $a2, overflow 
    # cause[6:2]=0x09
    ori $a2, $zero, 0x24
    beq $a1, $a2, break_exp
    # cause[6:2]=0x05 
    ori $a2, $zero, 0x14 
    beq $a1, $a2, store_addr_error
    # cause[6:2]=0x04 
    ori $a2, $zero, 0x10
    beq $a1, $a2, load_addr_error
    # cause[6:2]=0x08
    ori $a2, $zero, 0x20
    beq $a1, $a2, syscall_exp
    j error

overflow:
    addi $at, $at, 0x1 
    mfc0 $v1, $14
    addi $v1, $v1, 0x0004
    mtc0 $v1, $14
    nop
    eret

store_addr_error:
    ori $at, $zero, 0x5555 
    mfc0 $v1, $14
    addi $v1, $v1, 0x0004
    mtc0 $v1, $14
    nop
    eret

load_addr_error:
    ori $at, $zero, 0x4444 
    mfc0 $v1, $14
    addi $v1, $v1, 0x0004
    mtc0 $v1, $14
    nop
    eret

syscall_exp:
    ori $at, $zero, 0x8888 
    mfc0 $v1, $14
    addi $v1, $v1, 0x0004
    mtc0 $v1, $14
    # cp0 data_dep
    # mfc0 $a3, $14
    # bne $a3, $v1, error 
    nop
    eret

break_exp:
    ori $at, $zero, 0x9999 
    mfc0 $v1, $14
    addi $v1, $v1, 0x0004
    mtc0 $v1, $14
    nop
    eret

error:
    li $t3, 0xffffffff # 某一阶段处理发生错误
    j error